﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using Guru.Web.UI;
using System.Xml;
using System.Web.Caching;
using System.Web;
using System.Web.UI;

namespace Guru.Web.Controls
{
    internal interface IMultiLanguageLoader
    {
        void SetText(NameValueCollection textCollection);
        string ID { get; set; }
        Control Parent { get; }       
    }
    internal static class MultiLanguageHandler
    {       
        /// <summary>
        /// Load Text From resource file for a control
        /// </summary>
        /// <param name="ctrl"></param>
        /// <param name="page"></param>
        internal static void LoadTextFromResource(this IMultiLanguageLoader ctrl, string languageID)
        {
            string sessionID = GetPageTextResourceID(FindResourceParent(ctrl.Parent));
            if (string.IsNullOrEmpty(sessionID)) return;

            TextResourceManager textManager = new TextResourceManager(languageID);
            NameValueCollection textCollection = textManager.GetResources(sessionID, ctrl.ID);
            if (textCollection != null && textCollection.Count > 0)
            {
                ctrl.SetText(textCollection);
            }
        }
        /// <summary>
        /// Get SessionID of the page in Text the resource file
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        internal static string GetPageTextResourceID(Control ctr)
        {
            System.Reflection.MemberInfo info = ctr.GetType();
            object[] attributes = info.GetCustomAttributes(true);
            for (int i = 0; i < attributes.Length; i++)
            {
                if (attributes[i] is PageTextResource)
                {
                    PageTextResource obj = (PageTextResource)attributes[i];
                    return obj.ResourceKey;
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// Get TextResource Parent : Page or UserControl       
        /// </summary>
        /// <param name="ctrl"></param>
        /// <returns></returns>
        internal static Control FindResourceParent(Control ctrl)
        {  
            if (ctrl == null) return null;
            if (ctrl is Page || (ctrl is GuruUserControl && (ctrl.Page.Master != null))) return ctrl;
            return FindResourceParent(ctrl.Parent);
        }              
    }

    public class TextResourceManager
    {
        public const string GLOBAL_SESSIO_ID = "Common";
        protected const string TEXT_RES_TPL = "~/App_Data/texRes-{0}.xml";

        private string _FilePath;
        protected XmlDocument ResDocument
        {
            get
            {
                XmlDocument resDoc = null;
                if (System.Web.HttpRuntime.Cache["Guru.Web.Controls.TextResourceManager.TextResource"] == null)
                {
                    resDoc = new System.Xml.XmlDocument();
                    resDoc.Load(_FilePath);
                    HttpRuntime.Cache.Add("Guru.Web.Controls.TextResourceManager.TextResource", resDoc, new CacheDependency(_FilePath), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);

                }
                else
                {
                    resDoc = (XmlDocument)System.Web.HttpRuntime.Cache["Guru.Web.Controls.TextResourceManager.TextResource"];
                }
                return resDoc;
            }
        }
        
        public TextResourceManager(string languageID)
        {
            this._FilePath = HttpContext.Current.Server.MapPath(string.Format(TEXT_RES_TPL, languageID));
        }

        /// <summary>
        /// Get text in Common Session
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetGlobalText(string key)
        {
            return this.GetText(GLOBAL_SESSIO_ID, key);
        }

        /// <summary>
        ///  Get Text by Key
        /// </summary>
        /// <param name="sessionID"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetText(string sessionID, string key)
        {
            XmlDocument resDoc = this.ResDocument;
            XmlNodeList textNodes = resDoc.SelectNodes(string.Format("//res/sessions/session[@id='{0}']/text[@key='{1}']", sessionID, key));
            if (textNodes == null || textNodes.Count == 0) return string.Empty;
            else return textNodes[0].Attributes["value"].Value;
        }

        /// <summary>
        ///  Get Text & Child
        /// </summary>
        /// <param name="sessionID"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public NameValueCollection GetResources(string sessionID, string key)
        {
            NameValueCollection resources = new NameValueCollection();
            // Master Text
            string text = this.GetText(sessionID, key);
            if (!string.IsNullOrEmpty(text))
            {
                resources[key] = this.GetText(sessionID, key);
            }

            // Related Text: [MasterKey].[ChildKey]
            XmlNodeList textNodes = this.ResDocument.SelectNodes(string.Format("//res/sessions/session[@id='{0}']/text[contains(@key,'{1}.')]", sessionID, key));
            foreach (XmlNode node in textNodes)
            {
                resources[node.Attributes["key"].Value] = node.Attributes["value"].Value;
            }
            return resources;
        }
    }
}
